import WMTS from "ol/source/WMTS"
import ImageWMS from "ol/source/ImageWMS"
import WMTSTileGrid from "ol/tilegrid/WMTS"
import TileLayer from "ol/layer/Tile"
import TileArcGISRest from "ol/source/TileArcGISRest"
import LayerGroup from "ol/layer/Group"
import { get as getProjection } from "ol/proj"
import { getTopLeft, getWidth } from "ol/extent"
import VectorLayer from "ol/layer/Vector"
import VectorSource from "ol/source/Vector"
import ImageLayer from "ol/layer/Image"
import ImageStatic from "ol/source/ImageStatic"
import { fromExtent } from "ol/geom/Polygon"
import Feature from "ol/Feature"
// import { Select } from "ol/interaction"
// import { click } from "ol/events/condition"
import { v4 as uuidv4 } from 'uuid'
import { LAYER_GROUP_NAME, DEFAULT_PROJECTION, FEATURE_LAYER_ID } from '../constant/index'
import { getStyle } from '../feature/style'
export default {
  addWMTSMapLayer,
  addArcgisMapLayer,
  addWMSMapLayer,
  createLayerGroup,
  addGeoLayer,
  addVectorLayer,
  addLayer,
  getGroupLayers,
  getAllLayers,
  removeAllLayers,
  setImageLayer,
  updateImageLayer,
  removeLayer,
  addGrid
}

// function getStyle (options) {
//   const {
//     fillColor = "rgba( 255, 255, 255, 0.7)",
//     strokeColor = "#f4b49f",
//     strokeWidth = 3
//   } = options || {}

//   const style = new Style({
//     fill: new Fill({ color: fillColor }),
//     stroke: new Stroke({
//       color: strokeColor,
//       width: strokeWidth,
//     })
//   })
//   return style
// }

function addWMTSMapLayer (options) {
  const {
    id = uuidv4(),
    title,
    // visible = false,
    url,
    baseUrl,
    src,
    name,
    layer,// 图层名称
    matrixSet = 'c', // 切片网格级
    format = "tiles", // 请求格式
    style = "default", // 样式
    crossOrigin = "anonymous" //用于存图跨域
  } = options || {}

  const projection = getProjection(DEFAULT_PROJECTION)
  const projectionExtent = projection.getExtent()
  // const size = getWidth(projectionExtent) / 256

  const resolutions = new Array(19)
  const matrixIds = new Array(19)
  for (let z = 0; z < 20; ++z) {
    //1.40625
    // resolutions1[z] = size / Math.pow(2, z); //天地图经纬 度底图的计算参数
    resolutions[z] = 1.40625285 / Math.pow(2, z) //苍穹 底图计算参数
    matrixIds[z] = z
  }

  const tileGrid = new WMTSTileGrid({
    origin: getTopLeft(projectionExtent),// 原点（左上角）
    resolutions, // 分辨率数组
    matrixIds, // 矩阵ID，就是瓦片坐标系z维度各个层级的标识
  })

  const source = new WMTS({
    name: title,
    url,
    // url: src,
    layer,
    style,
    matrixSet,
    format,
    wrapX: true,
    tileGrid,
    // crossOrigin, //用于存图跨域
  })

  // 设置自定义的瓦片 URL 函数
  source.setTileUrlFunction(function (tileCoord) {
    console.log('tileCoord...', baseUrl, tileCoord)
    const [tilematrix, tilecol, tilerow] = tileCoord || []
    return `${baseUrl}&TILEMATRIX=${tilematrix}&TILECOL=${tilecol}&TILEROW=${tilerow}`
  })
  const mapLayer = new TileLayer({
    // id,
    // title,
    // visible,
    source
  })
  return mapLayer
}
/**
 * 添加arcgis瓦片服务图层
 * @param {string} layerName 图层名称
 * @param {string} url 图层路径
 * @return {TileLayer} 图层对象
 */
function addArcgisMapLayer (options) {
  const { url, layerName } = options || {}
  if (!url) {
    throw new Error('addArcgisMapLayer方法入参url不能为空')
  }
  const arcLayer = new TileLayer({
    source: new TileArcGISRest({
      url,
      wrapX: false,
    }),
    properties: {
      [LAYER_GROUP_NAME]: layerName
    }
  })
  return arcLayer
}

function addWMSMapLayer (opts) {
  const {
    zIndex = 2,
    ratio = 1,
    url = `${process.env.VUE_APP_BASE_API}/geoserverA/geoserver/cite/wms`,
    layers,
    name,
    opacity = 1,
    version = '1.1.0',
    request = "GetMap",
    styles = '',
    format = 'image/png',
    layerName
  } = opts || {}

  const source = new ImageWMS({
    ratio,
    url,
    params: {
      //service: 'WMS',
      VERSION: version,
      request,
      LAYERS: layers,
      STYLES: styles,
      FORMAT: format
    },
  })
  const imageLayer = new ImageLayer({
    zIndex,
    name,
    source,
    opacity,
    properties: {
      [LAYER_GROUP_NAME]: layerName
    }
  })
  this.map.addLayer(imageLayer)
}

/**
 * 创建图层分组
 * @param {String} groupName 组名 
 * @param {Array} layers 图层数组 
 * @param {String} zIndex 层级 
 * @returns 
 */
function createLayerGroup (options) {
  const { groupName, layers = [], zIndex = 0, properties = {} } = options || {}
  const layerGroup = new LayerGroup({
    layers,
    zIndex,
    properties: {
      ...properties,
      layerName: groupName
    }
  })
  return layerGroup
}

function addGeoLayer (options) {
  const {
    zIndex = 10,
    fillColor = "rgba( 255, 255, 255, 0.7)",
    strokeColor = "#f4b49f",
    strokeWidth = 3,
    layerName = "遮罩图层"
  } = options || {}
  const geolayer = this.addVectorLayer({
    zIndex,
    declutter: false, //防止标注文字重复标注
    fillColor,
    strokeColor,
    strokeWidth,
    layerName
  })
  this.map.addLayer(geolayer)
}

/**
 * 添加矢量图层
 * @param {*} opts 
 * @returns 
 */
function addVectorLayer (opts) {
  const {
    // features,
    zIndex,
    declutter,
    layerName,
    properties = {},
    fillColor,
    strokeColor,
    strokeWidth,
    style,
    sourceConfig
  } = opts || {}
  // const config = features ? { features } : undefined
  const config = sourceConfig ? { wrapX: false } : sourceConfig
  layerName && Object.assign(properties, {
    [LAYER_GROUP_NAME]: layerName
  })
  const vectorLayer = new VectorLayer({
    source: new VectorSource(config),
    zIndex,
    declutter,
    style: function (feature) {
      return styleFunction ? styleFunction(feature) : getStyle({
        fillColor,
        strokeColor,
        strokeWidth
      })
    },
    properties
  })
  return vectorLayer
}
/**
  * 获取所有的图层
  * @returns 
  */
function getAllLayers () {
  return this.map.getLayers().getArray()
}
function getGroupLayers (layer) {
  return layer.getLayers().getArray()
}
function removeAllLayers () {
  this.getAllLayers().forEach((layer) => {
    const layerSource = layer.getSource()
    if (layer instanceof LayerGroup) {
      this.getGroupLayers(layer).forEach((layerItem) => {
        layerItem.getSource().clear()
      })
    } else if (layerSource instanceof VectorSource) {
      layerSource.clear()
    }
    layer.dispose()
    this.map.removeLayer(layer)
  })
  this.map.getLayers().clear()
}
function addLayer (features, options) {
  const {
    fillColor,
    strokeColor,
    strokeWidth,
    layerName
  } = options || {}

  const layer = this.getAllLayers().find(v => v.get('id') === FEATURE_LAYER_ID)
  if (!layer) {
    const featureLayer = this.addVectorLayer({
      sourceConfig: { features },
      style (feature) {
        return utils.getStyle(feature, context)
      },
      // fillColor,
      // strokeColor,
      // strokeWidth,
      properties: {
        id: FEATURE_LAYER_ID,
        [LAYER_GROUP_NAME]: layerName
      }
    })
    this.map.addLayer(featureLayer)
  } else {
    layer.getSource().addFeatures(features)
  }
}
function setImageLayer (opts) {
  const {
    url,
    extent: imageExtent,
    layerName,
    zIndex = 11,
    opacity = 1
  } = opts || {}
  const imageLayer = new ImageLayer({
    zIndex,
    opacity,
    // name: `Layer${layername}`,
    properties: {
      [LAYER_GROUP_NAME]: layerName
    }
  })
  const imageStatic = new ImageStatic({ url, imageExtent })
  // 更新图片图层的源
  imageLayer.setSource(imageStatic)
  this.map.addLayer(imageLayer)
}
/**
 * 修改图片图层的图片
 * @param {*} opts 
 */
function updateImageLayer (opts) {
  const { url, extent: imageExtent, layerName } = opts || {}
  const config = url ? new ImageStatic({ url, imageExtent }) : null
  const layer = this.getAllLayers().find(v => v.get(LAYER_GROUP_NAME) === layerName)
  layer.setSource(config)
}

function removeLayer (opts) {
  const { layerName } = opts
  const layer = this.getAllLayers().find((v) => v.get(LAYER_GROUP_NAME) === layerName)
  layer && this.map.removeLayer(layer)
}


/**
 * 添加网格
 * @param {*} opts
 */
function addGrid (opts) {
  const { extent, precision, layerName = 'gridLayer' } = opts || {}
  let max = -999999999999
  let min = 999999999999
  const features = []
  const [startLng, startLat, endLng, endLat] = extent.map((v) => v * precision)
  const size = opts.size * precision
  const columns = (endLng - startLng) / size
  const rows = (endLat - startLat) / size

  //构造网格,不要边界
  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < columns; j++) {
      //[经度，纬度]
      const left = lonStart + j * size //左
      const right = left + size //右上
      const bottom = latStart + i * size //右下
      const top = bottom + size
      //随机生成value
      const value = Math.floor(Math.random() * 101) // 返回 0 至 100 之间的数
      max = value > max ? value : max
      min = value < min ? value : min
      const extent = [
        left / precision,
        bottom / precision,
        right / precision,
        top / precision,
      ]
      features.push(
        new Feature({
          geometry: fromExtent(extent),
          value
        })
      )
    }
  }

  function styleFunction (feature) {
    const v = feature.get("value")
    const fillColor = "#00fff8"
    if (v >= 0 && v <= 20) {
      fillColor = "#00fff876";
    } else if (v > 20 && v <= 40) {
      fillColor = "#00ff1076"
    } else if (v > 40 && v <= 60) {
      fillColor = "#f9ff0076"
    } else if (v > 60 && v <= 80) {
      fillColor = "#ffb30076"
    } else if (v > 80 && v <= 100) {
      color = "#ff1b0076"
    }
    return getStyle({
      fillColor,
      strokeColor: "#7a7a7a",
      strokeWidth: 0.5
    })
  }

  const vectorLayer = this.addVectorLayer({
    sourceConfig: { features },
    zIndex: 11,
    layerName,
    styleFunction
  })
  this.map.addLayer(vectorLayer)
  return { max, min }
  // const selectClick = new Select({
  //   // 事件类型
  //   condition: click,
  //   layers: [vectorLayer],
  //   // 点击后的样式
  //   style: function () {
  //     return new Style({
  //       fill: new Fill({
  //         color: "rgba(255,0,0,0.2)",
  //       }),
  //       stroke: new Stroke({
  //         color: "rgba(255,0,0,1)",
  //         width: 5,
  //       }),
  //     })
  //   }
  // })
  // this.map.addInteraction(selectClick)
}